//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.UIDesigner.ActivityImportWizards
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Configuration;
    using System.Diagnostics;
    using System.IO;
    using System.Reflection;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
    using Microsoft.Research.ScientificWorkflow.TridentComposer;
    using Microsoft.Research.ScientificWorkflow.TridentModel;
    using Microsoft.Research.ScientificWorkflow.TridentUtilities;
    using Microsoft.Research.ScientificWorkflow.UIDesigner;
    using Microsoft.Research.DataLayer;
    using System.Xml;
    using System.Globalization;

    /// <summary>
    /// 
    /// </summary>
    public class WSWizardPresenter : IActivityPresenter, INotifyPropertyChanged
    {
        private static string cscPath;
        private static string wsdlPath;
        private static int wsTimeout;
        private const string TridentDllName = "ScientificWorkflow.TridentWorkflowCommon.dll";
        private XmlDocument xmlDoc = new XmlDocument();
        private string currentAssemblyName = string.Empty;
        private string URL_PARAM = "Url";

        // Create the Model Object for wizard
        public WebServiceWizardModel WSModel
        {
            get;
            set;
        }
   
        public Connection RegistryHandle
        {
            get;
            set;
        }

        public UIHelper Helper
        {
            get;
            set;
        }

        public WSWizardPresenter(Connection registryHandle)
        {
            this.WSModel = new WebServiceWizardModel();
            currentAssemblyName = System.Reflection.Assembly.GetEntryAssembly().ManifestModule.Name;

            if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, currentAssemblyName + ".config")))
            {
                xmlDoc.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, currentAssemblyName + ".config"));
            }

            // Check if CSC.EXE and WSDL.EXE is avaialbale.
            CheckSystemTools();

            string timeOut = ConfigurationManager.AppSettings["WebServiceTimeOutInMilliSeconds"];
            if (!string.IsNullOrEmpty(timeOut))
                wsTimeout = Int32.Parse(timeOut, CultureInfo.InvariantCulture);

            this.RegistryHandle = registryHandle;

            Helper = new UIHelper(this.RegistryHandle);
        }

        #region Selection Screen

        /// <summary>
        /// Initializes this instance.
        /// </summary>
        internal void Initialize()
        {
            WSModel.ActivityDescription = string.Empty;
            WSModel.ActivityName = string.Empty;
            WSModel.ActivityImageSource = string.Empty;
            WSModel.ActivityCategory = string.Empty;
            WSModel.OutputBinariesPath = string.Empty;
            WSModel.SelectedWebMethod = string.Empty;
            WSModel.SelectedWebMethodParamList.Clear();
            WSModel.IsCopyActivityCodeEnabled = false;
            WebServiceWizardModel.ActivityTempPath = string.Empty;
            WebServiceWizardModel.ProxyTempPath = string.Empty;
        }

        /// <summary>
        /// Resets on connect.
        /// </summary>
        internal void ResetConnect()
        {
            WSModel.ActivityTypes.Clear();
            WSModel.AvailableWebMethods.Clear();
            WSModel.ParameterInfo.Clear();
            WSModel.ActivityDescription = string.Empty;
            WSModel.ActivityName = string.Empty;
            WSModel.ActivityImageSource = string.Empty;
            WSModel.ActivityCategory = string.Empty;
            WSModel.SelectedWebMethod = string.Empty;
            WSModel.SelectedWebMethodParamList.Clear();
            WSModel.IsCopyActivityCodeEnabled = false;
        }

        /// <summary>
        /// Checks the system tools.
        /// </summary>
        /// <returns></returns>
        public bool CheckSystemTools()
        {
            try
            {
                // If already assigned.
                if (!File.Exists(cscPath) || !File.Exists(wsdlPath))
                {
                    // First try to get from default settings.
                    cscPath = Path.Combine(Environment.ExpandEnvironmentVariables("%SystemRoot%"), @"Microsoft.NET\Framework\v3.5\csc.exe");
                    string ExeFilter = "Executable files (*.exe)|*.exe";
                    if (!File.Exists(cscPath))
                    {
                        // Try to get it from config file.
                        cscPath = ConfigurationManager.AppSettings["CSCPath"];

                        // At last try to get it from user as input.
                        if (!File.Exists(cscPath))
                        {
                            cscPath = WSWizardPresenter.FileBrowse("CSC.exe", ExeFilter);
                            UpdateKey("CSCPath", cscPath);
                        }
                    }

                    string programFilesPath = string.Empty;
                    if (8 == IntPtr.Size || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432")))
                    {
                        programFilesPath = Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%");
                    }
                    else
                    {
                        programFilesPath = Environment.ExpandEnvironmentVariables("%ProgramFiles%");
                    }

                    // First try to get from default settings.
                    wsdlPath = Path.Combine(programFilesPath, @"Microsoft SDKs\Windows\v6.0A\Bin\wsdl.exe");

                    if (!File.Exists(wsdlPath))
                    {
                        // Try to get it from config file.
                        wsdlPath = ConfigurationManager.AppSettings["WSDLPath"];

                        // At last try to get it from user as input.
                        if (!File.Exists(wsdlPath))
                        {
                            wsdlPath = WSWizardPresenter.FileBrowse("WSDL.exe", ExeFilter);
                            UpdateKey("WSDLPath", wsdlPath);
                        }
                    }
                }

                return true;
            }
            catch (Exception exp)
            {
                TridentMessageBox.ShowTridentErrorMessageBox(TridentResourceManager.GetString("SystemToolsError") + exp.Message);
                return false;
            }
        }

        /// <summary>
        /// Updates the application config key.
        /// </summary>
        /// <param name="strKey">The key.</param>
        /// <param name="newValue">The new value.</param>
        public void UpdateKey(string stringKey, string newValue)
        {
            if (!KeyExists(stringKey))
                throw new ArgumentException("Key", "<" + stringKey +
                      "> does not exist in the configuration. Update failed.");
            XmlNode appSettingsNode =
               xmlDoc.SelectSingleNode("configuration/appSettings");
            // Attempt to locate the requested setting.
            foreach (XmlNode childNode in appSettingsNode)
            {
                if (childNode.Attributes["key"].Value == stringKey)
                    childNode.Attributes["value"].Value = newValue;
            }
            xmlDoc.Save(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, currentAssemblyName + ".config"));
            xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
        }

        /// <summary>
        /// Determines if a key exists within the application config.
        /// </summary>
        /// <param name="strKey">The STR key.</param>
        /// <returns></returns>
        private bool KeyExists(string strKey)
        {
            XmlNode appSettingsNode =
              xmlDoc.SelectSingleNode("configuration/appSettings");
            // Attempt to locate the requested setting.
            foreach (XmlNode childNode in appSettingsNode)
            {
                if (childNode.Attributes["key"].Value == strKey)
                    return true;
            }
            return false;
        }

        #region Generate Proxy

        /// <summary>
        /// Generates the proxy for web service.
        /// </summary>
        /// <param name="wsdlPath">WSDL path.</param>
        /// <returns></returns>
        public void GenerateProxy(object wsdlPath)
        {
            try
            {
                string fileName = Guid.NewGuid().ToString();

                // Update the common temp path.
                Guid guidPath = Guid.NewGuid();
                WebServiceWizardModel.TempPath = Path.Combine(WebServiceWizardModel.TempPath, guidPath.ToString());
                if (!Directory.Exists(WebServiceWizardModel.TempPath))
                {
                    Directory.CreateDirectory(WebServiceWizardModel.TempPath);
                }

                // Update the proxy temp path.
                string proxyCodePath = Path.Combine(WebServiceWizardModel.TempPath, Path.GetFileNameWithoutExtension(fileName) + ".cs");
                WebServiceWizardModel.ProxyTempPath = proxyCodePath.Replace(".cs", ".dll");

                // If proxy code generated.
                if (WSWizardPresenter.GenerateProxyCode(wsdlPath as string, proxyCodePath))
                {
                    // Generate the proxy assembly.
                    WSWizardPresenter.CompileProxyCode(proxyCodePath, WebServiceWizardModel.ProxyTempPath);
                }
            }
            catch (Exception e)
            {
                TridentMessageBox.ShowTridentErrorMessageBox("Error in generating proxy : " + e.Message);
            }
        }

        /// <summary>
        /// Generates the proxy code.
        /// </summary>
        /// <param name="wsdlUri">The WSDL URI.</param>
        /// <param name="modelCodePath">The model code path.</param>
        /// <returns></returns>
        private static bool GenerateProxyCode(string wsdlUri, string modelCodePath)
        {
            bool isProxyCodeCreated = true;
            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo(WSWizardPresenter.wsdlPath);
                StringBuilder arguments = new StringBuilder();
                arguments.Append(wsdlUri);
                arguments.Append(" /namespace:" + WebServiceWizardModel.ActivityNamespace);
                arguments.Append(" /out:\"");
                arguments.Append(Path.GetFullPath(modelCodePath));
                arguments.Append('\"');
                startInfo.Arguments = arguments.ToString();

                startInfo.WindowStyle = ProcessWindowStyle.Hidden;

                using (Process proc = Process.Start(startInfo))
                {
                    proc.WaitForExit();
                }

                // If proxy not code generated.
                if (!File.Exists(modelCodePath))
                {
                    throw new FileNotFoundException();
                }

                return isProxyCodeCreated;
            }
            catch (FileNotFoundException)
            {
                TridentMessageBox.ShowTridentErrorMessageBox("Could not get available WebMethods." +
                    "Possible reasons :\r\n1. Service is not available.\r\n2. Invalid URL.\r\n3. Path for Csc.exe or Wsdl.exe is invalid.");

                return isProxyCodeCreated = false;
            }
            catch (Exception e)
            {
                TridentMessageBox.ShowTridentErrorMessageBox("Error in getting WebMethods : " + e.Message);
                isProxyCodeCreated = false;
            }

            return isProxyCodeCreated;
        }

        /// <summary>
        /// Compiles the proxy code.
        /// </summary>
        /// <param name="modelCodePath">The model code path.</param>
        /// <param name="dllPath">The DLL path.</param>
        /// <returns></returns>
        private static bool CompileProxyCode(string modelCodePath, string dllPath)
        {
            bool isProxyAssemblyCreated = true;

            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo(WSWizardPresenter.cscPath);
                StringBuilder arguments = new StringBuilder();
                arguments.Append("/target:library ");
                arguments.Append("/out:\"");
                arguments.Append(dllPath);
                arguments.Append("\" \"");
                arguments.Append(modelCodePath);
                arguments.Append('\"');
                startInfo.Arguments = arguments.ToString();

                startInfo.WindowStyle = ProcessWindowStyle.Hidden;

                using (Process proc = Process.Start(startInfo))
                {
                    proc.WaitForExit();
                }

                // If proxy assembly generated.
                if (!File.Exists(dllPath))
                {
                    throw new FileNotFoundException();
                }

                return isProxyAssemblyCreated;
            }
            catch (FileNotFoundException)
            {
                TridentMessageBox.ShowTridentErrorMessageBox("Could not generate Web Service Activity. " +
                    "Possible reasons :\r\n1. Service is not available.\r\n2. Invalid URL.\r\n3. Path for Csc.exe or Wsdl.exe is invalid.");
                return false;
            }
            catch (Exception)
            {
                TridentMessageBox.ShowTridentErrorMessageBox("Could not generate Web Service Activity. " +
                    "Possible reasons :\r\n1. Service is not available.\r\n2. Invalid URL.\r\n3. Path for Csc.exe or Wsdl.exe is invalid.");
                return isProxyAssemblyCreated = false;
            }
        }

        #endregion

        /// <summary>
        /// Gets the available web methods.
        /// </summary>
        /// <param name="proxyDllPath">The proxy DLL path.</param>
        public bool GetAvailableWebMethods(string proxyDllPath)
        {
            try
            {
                bool isWebMethodFound = false;
                Type modelSuperType = typeof(System.Web.Services.Protocols.SoapHttpClientProtocol);
                Type attributeType = typeof(System.Web.Services.Protocols.SoapDocumentMethodAttribute);
                Assembly proxyAsm = Assembly.LoadFile(Path.GetFullPath(proxyDllPath));
                Type[] allTypes = proxyAsm.GetExportedTypes();

                // For each available type.
                foreach (Type modelType in allTypes)
                {
                    if (!modelType.IsSubclassOf(modelSuperType))
                        continue;

                    // Get all the methods available in the service.
                    MemberInfo[] mbrInfoArray = modelType.GetMethods();

                    // Loop all methodes to get the WebMethods
                    foreach (MemberInfo mbrInfo in mbrInfoArray)
                    {
                        bool isWebMethod = false;
                        object[] attribs = mbrInfo.GetCustomAttributes(false);
                        for (int i = 0; i < attribs.Length; i++)
                        {
                            // Web Method will have this attribute.
                            if (attribs[i].GetType() == attributeType)
                            {
                                isWebMethod = true;
                                break;
                            }
                        }

                        // If WebMethod, get all the parameters.
                        if (isWebMethod)
                        {
                            WSModel.AvailableWebMethods.Add(mbrInfo.Name);
                            GetWebMethodParameters(mbrInfo as MethodInfo);

                            // Update it with activity Name
                            WSModel.ActivityTypes.Add(mbrInfo.Name, modelType);
                        }
                    }

                    if (WSModel.AvailableWebMethods.Count > 0)
                        WSModel.SelectedWebMethod = WSModel.AvailableWebMethods[0];
                }

                if (WSModel.AvailableWebMethods.Count > 0)
                {
                    isWebMethodFound = true;
                }

                return isWebMethodFound;
            }
            catch (Exception exp)
            {
                TridentMessageBox.ShowTridentErrorMessageBox(TridentResourceManager.GetString("WebMehthodRetrivalError") + exp.Message);
                return false;
            }
        }

        /// <summary>
        /// Gets the web method parameters.
        /// </summary>
        /// <param name="mbrInfo">The method information.</param>
        private void GetWebMethodParameters(MethodInfo methodInfo)
        {
            try
            {
                ObservableCollection<WebMethodParameterInfo> parametersInfo = new ObservableCollection<WebMethodParameterInfo>();
                ParameterInfo[] inputParameters = methodInfo.GetParameters();
                ParameterInfo outputParameter = methodInfo.ReturnParameter;

                // Assign Input Parameters.            
                foreach (ParameterInfo inputParameter in inputParameters)
                {
                    AssignParameters(parametersInfo, inputParameter, ParameterDirection.In);
                }
                
                WebMethodParameterInfo param = new WebMethodParameterInfo();
                param.IsBuiltIn = true;
                param.WebMethodParamName = URL_PARAM;
                param.ActivityParamName = URL_PARAM;
                param.DefaultValue = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", ActivityCodeGenerator.Webservice_Url);
                param.IsRequired = "Yes";
                param.ParamDirection = ParameterDirection.In;
                param.ParamType = "System.String";
                parametersInfo.Add(param);

                // Assign output parameter.            
                if (outputParameter.ParameterType.Name != "Void")
                {
                    AssignParameters(parametersInfo, outputParameter, ParameterDirection.Out);
                }

                // Add all paremeters in KeyValue pair for this method.
                WSModel.ParameterInfo.Add(methodInfo.Name, parametersInfo);
            }
            catch (Exception exp)
            {
                TridentMessageBox.ShowTridentErrorMessageBox(TridentResourceManager.GetString("WebMehthodRetrivalError") + exp.Message);
            }
        }

        /// <summary>
        /// Assigns the parameters.
        /// </summary>
        /// <param name="parametersInfo">List of all parameters.</param>
        /// <param name="parameter">WebMethod parameter.</param>
        /// <param name="ParameterDirection">The direction of parameter.</param>
        private static void AssignParameters(
            ObservableCollection<WebMethodParameterInfo> parametersInfo,
            ParameterInfo parameter, ParameterDirection direction)
        {
            WebMethodParameterInfo param = new WebMethodParameterInfo();

            if (direction == ParameterDirection.Out)
            {
                param.WebMethodParamName =
                    string.IsNullOrEmpty(parameter.Name) ? "Result" : parameter.Name;
            }
            else
            {
                param.WebMethodParamName = parameter.Name;
            }

            param.ActivityParamName = param.WebMethodParamName;
            param.IsRequired = (!parameter.IsOptional) ? "Yes" : "No";
            param.ParamDirection = direction;
            param.ParamType = parameter.ParameterType.FullName;

            parametersInfo.Add(param);
        }

        #endregion

        #region Customization Screen

        /// <summary>
        /// Gets the activity category.
        /// </summary>
        /// <param name="tree">The tree.</param>
        public void GetActivityCategory(Category tree)
        {
            if (null != (tree as Category).Parent)
            {
                GetActivityCategory(tree.Parent);

                if (!string.IsNullOrEmpty(this.WSModel.ActivityCategory))
                    this.WSModel.ActivityCategory = this.WSModel.ActivityCategory + @"/" + (tree as Category).Name;
                else
                    this.WSModel.ActivityCategory = (tree as Category).Name;
            }
        }

        /// <summary>
        /// Generates the activity for preview.
        /// </summary>
        /// <returns></returns>
        public bool GenerateActivity()
        {
            try
            {
                string activityCode = ActivityCodeGenerator.GenerateActivityCode(this.WSModel);

                string outputFolder = (this.WSModel.IsCopyActivityCodeEnabled && !string.IsNullOrEmpty(this.WSModel.OutputBinariesPath))
                    ? this.WSModel.OutputBinariesPath :
                    WebServiceWizardModel.TempPath;

                string activityCodePath = Path.GetFullPath(Path.Combine(outputFolder, Guid.NewGuid().ToString() + ".cs"));
                StreamWriter sw = new StreamWriter(activityCodePath);
                sw.Write(activityCode);
                sw.Flush();
                sw.Close();
                return WSWizardPresenter.CompileActivityCode(activityCodePath);
            }
            catch (Exception exp)
            {
                TridentMessageBox.ShowTridentErrorMessageBox(TridentResourceManager.GetString("ActivityGenerationError") + exp.Message);
                return false;
            }
        }

        private static bool CompileActivityCode(string activityCodePath)
        {
            bool isProxyAssemblyCreated = true;

            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo(WSWizardPresenter.cscPath);
                StringBuilder arguments = new StringBuilder();
                string proxyPath = WebServiceWizardModel.ProxyTempPath.Replace(".dll", ".cs");
                WebServiceWizardModel.ActivityTempPath = activityCodePath.Replace(".cs", ".dll");

                arguments.Append("/target:library ");
                arguments.Append("/out:\"");
                arguments.Append(WebServiceWizardModel.ActivityTempPath);
                arguments.Append("\" \"");
                arguments.Append(proxyPath);
                arguments.Append("\" \"");
                arguments.Append(activityCodePath);
                arguments.Append('\"');
                arguments.Append(" /reference:\"");
                arguments.Append(AppDomain.CurrentDomain.BaseDirectory);
                arguments.Append("\\" + TridentDllName + "\"");
                startInfo.Arguments = arguments.ToString();

                startInfo.WindowStyle = ProcessWindowStyle.Hidden;

                using (Process proc = Process.Start(startInfo))
                {
                    proc.WaitForExit();
                }

                if (!File.Exists(WebServiceWizardModel.ActivityTempPath))
                {
                    throw new FileNotFoundException();
                }

                return isProxyAssemblyCreated;
            }
            catch (FileNotFoundException)
            {
                TridentMessageBox.ShowTridentErrorMessageBox("Could not generate Web Service Activity. " +
                    "Possible reasons :\r\n1. Service is not available.\r\n2. Invalid URL.\r\n3. Path for Csc.exe or Wsdl.exe is invalid.");
                return false;
            }
            catch (Exception)
            {
                TridentMessageBox.ShowTridentErrorMessageBox("Could not generate Web Service Activity. " +
                    "Possible reasons :\r\n1. Service is not available.\r\n2. Invalid URL.\r\n3. Path for Csc.exe or Wsdl.exe is invalid." );
                return false;
            }
        }

        /// <summary>
        /// Reads the activity categories.
        /// </summary>
        internal void GetActivityCategories()
        {
            try
            {
                Category parentCategory = new Category();
                User user = User.Get(CategoriesComposer.SystemUserName, this.RegistryHandle);
                Namespace activityRoot = user.ActivityRoot;

                parentCategory = CreateCategoryTree(activityRoot, parentCategory);

                WSModel.CategoryList.Clear();
                WSModel.CategoryList = parentCategory.Children;
            }
            catch (Exception exp)
            {
                TridentMessageBox.ShowTridentErrorMessageBox(
                    TridentResourceManager.GetString("CategoryTreeGenerationError") + exp.Message);
            }

        }

        /// <summary>
        /// Creates the category tree.
        /// </summary>
        /// <param name="activityRoot">The activity root.</param>
        /// <param name="parent">The parent.</param>
        /// <returns></returns>
        private Category CreateCategoryTree(Namespace activityRoot, Category parent)
        {
            // Get all the root namespace.
            NamespaceCollection<Namespace> x = activityRoot.Children;

            foreach (Namespace cat in x)
            {
                Category child = new Category();

                child.Name = string.IsNullOrEmpty(cat.Label) ? cat.Name : cat.Label;
                child.Parent = parent;


                if (null == this.WSModel.SelectedCategory)
                {
                    if (CategoriesComposer.WebServiceActivitiesName.Equals(child.Name))
                    {
                        this.WSModel.SelectedCategory = child;
                        child.IsSelected = true;
                    }
                }
                else
                {
                    if (this.WSModel.SelectedCategory.Name.Equals(child.Name))
                    {
                        this.WSModel.SelectedCategory = child;
                        child.IsSelected = true;
                    }
                }

                parent.Children.Add(child);

                // For every child category make a recursive call to create it's tree.
                CreateCategoryTree(cat, child);
            }

            return parent;
        }

        #endregion

        #region Preview screen

        /// <summary>
        /// Loads the activity preview.
        /// </summary>
        /// <returns></returns>
        public ITridentUIElement LoadActivityPreview()
        {
            try
            {
                Collection<ParameterDescriptionModel> inputParamCollecion =
                    new Collection<ParameterDescriptionModel>();

                Collection<ParameterDescriptionModel> outputParamCollecion =
                    new Collection<ParameterDescriptionModel>();

                foreach (WebMethodParameterInfo param in this.WSModel.SelectedWebMethodParamList)
                {
                    bool isInput = (param.ParamDirection == ParameterDirection.In) ? true : false;
                    bool isRequired = (param.IsRequired.Equals("Yes")) ? true : false;

                    ParameterDescriptionModel paramModel =
                        new ParameterDescriptionModel(
                            param.ActivityParamValidName,
                            param.ActivityParamName,
                            "",
                            param.ParamType,
                            isInput,
                            !isInput,
                            isRequired);

                    if (isInput)
                    {
                        inputParamCollecion.Add(paramModel);
                    }
                    else
                    {
                        outputParamCollecion.Add(paramModel);
                    }
                }

                // Check before creating preview.
                if (string.IsNullOrEmpty(this.WSModel.ActivityName))
                {
                    this.WSModel.ActivityName = this.WSModel.SelectedWebMethod;
                }

                SimpleActivityModel activityModel = new SimpleActivityModel(
                    this.WSModel.ActivityName,
                    this.WSModel.ActivityDescription,
                    this.WSModel.ActivityName,
                    this.WSModel.ActivityName,
                    inputParamCollecion,
                    outputParamCollecion);

                // Set preview mode.
                activityModel.IsPreview = true;

                // Pass a blank dataType
                Dictionary<string, DataTypeModel> dataTypes = new Dictionary<string, DataTypeModel>();

                // Get the mapped UI.
                return UIHelper.LoadActivity(activityModel, dataTypes);
            }
            catch (Exception exp)
            {
                TridentMessageBox.ShowTridentErrorMessageBox(
                    TridentResourceManager.GetString("PreviewLoadError") + exp.Message);
                return null;
            }
        }

        #endregion

        #region Common Function

        /// <summary>
        /// Folders browse function.
        /// </summary>
        /// <returns></returns>
        public static string FolderBrowse()
        {
            string selectedPath = string.Empty;
            FolderBrowserDialog folder = new FolderBrowserDialog();
            folder.ShowNewFolderButton = true;
            folder.Description = "Copy Activity";
            folder.RootFolder = Environment.SpecialFolder.MyComputer;

            if (folder.ShowDialog() == DialogResult.OK)
            {
                selectedPath = folder.SelectedPath;
            }

            return selectedPath;
        }

        /// <summary>
        /// Gets the system tools path.
        /// </summary>
        /// <param name="tool">The tool.</param>
        /// <returns></returns>
        public static string FileBrowse(string tool, string filter)
        {
            OpenFileDialog fileDialogue = new OpenFileDialog();
            fileDialogue.Filter = filter;
            fileDialogue.InitialDirectory = Environment.SpecialFolder.MyComputer.ToString();
            fileDialogue.Title = "Searching for " + tool;

            return (fileDialogue.ShowDialog() == DialogResult.OK)
               ? fileDialogue.FileName : null;
        }

        #endregion

        #region IActivityPresenter Members




        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Fires the property changed event.
        /// </summary>
        /// <param name="propertyName">Name of the property which has been modified.</param>
        private void OnNotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        /// <summary>
        /// Browses the icon file.
        /// </summary>
        internal void BrowseIconFile()
        {
            string iconFilterString = "Icon Files (*.ico; *.bmp; *.png)|*.ico;*.bmp;*.png"; ;
            string iconPath = WSWizardPresenter.FileBrowse("Icon", iconFilterString);

            if (!string.IsNullOrEmpty(iconPath))
            {
                string selectedExtn = System.IO.Path.GetExtension(iconPath);
                bool validFile = (selectedExtn.Equals(".png", StringComparison.OrdinalIgnoreCase)
                    || selectedExtn.Equals(".ico", StringComparison.OrdinalIgnoreCase)
                    || selectedExtn.Equals(".bmp", StringComparison.OrdinalIgnoreCase));
                if (validFile)
                {
                    this.WSModel.ActivityImageSource = iconPath;
                }
                else
                {
                    TridentMessageBox.ShowTridentErrorMessageBox(ManagementStudioResourceManager.GetString("InvalidImageFileSelection"));
                    this.BrowseIconFile();
                }
            }
        }
    }
}
